<?php
/**
 * Created by PhpStorm.
 * User: bzing
 * Date: 2017-07-31
 * Time: 13:35
 */
namespace app\api\controller;
use app\models\Models;

class ApplePay extends Base{
    /**
     * 21000 App Store不能读取你提供的JSON对象
     * 21002 receipt-data域的数据有问题
     * 21003 receipt无法通过验证
     * 21004 提供的shared secret不匹配你账号中的shared secret
     * 21005 receipt服务器当前不可用
     * 21006 receipt合法，但是订阅已过期。服务器接收到这个状态码时，receipt数据仍然会解码并一起发送
     * 21007 receipt是Sandbox receipt，但却发送至生产系统的验证服务
     * 21008 receipt是生产receipt，但却发送至Sandbox环境的验证服务
     *
     * receipt  苹果返回的支付凭证，ios客户端base64加密后的长字符串
     * sandbox  为1时$url为测试地址，不传时为正试地址
     * transaction_id  苹果订单号
     */
    public function applePay(){
        if(request()->isPost()){
            $tran = new Models();
            try{
                // 登录验证
                $params = self::checkLogin(['equipment','encrypt']);
                // 查询订单
                $order = new Models('order');
                $info = $order->_find(['trade_no'=>$params['transaction_id']]);
                if($info){
                    throw new \LogicException('订单已存在',1037);
                }
                /**
                 * 获取产品信息
                 * 苹果支付不直接传金额，以产品形式
                 */
                $product = new Models('recharge_type');
                $pro_info = $product->_find(['id'=>$params['product_id']]);
                $tran->startTrans();
                // 添加订单
                $control = new Order();
                $data = [
                    'uid'          => $params['uid'],
                    'pid'          => $params['product_id'],
                    'type_id'      => Models::ORDER_TYPE_RECHARGE,
                    'order_amount' => $pro_info['price'],
                    'trade_no'     => $params['transaction_id'],
                ];
                $bool = $control->orderAdd($data);

                //去苹果进行二次验证，防止收到的是伪造的数据
                $result = $this->appleReceipt($params['receipt'],$params['sandbox']);
                if(!is_array($result)){
                    throw new \LogicException('操作失败',1010);
                }

                // 修改订单状态
                $bool1 = $order->_save(['status'=>Models::ORDER_PAY_YES,'pay_time'=>time()]);
                if (!$bool || !$bool1) {
                    $tran->rollback();
                    throw new \LogicException('操作失败',1010);
                }
            } catch (\Exception $e){
                return json(self::formatResult($e->getCode(),$e->getMessage()));
            }
            $tran->commit();
            return json(self::formatSuccessResult());
        }
    }

    /**
     * 去苹果服务器二次验证
     * @param $receipt
     * @param $sandbox
     * @return array
     */
    protected function appleReceipt($receipt,$sandbox = ''){
        $postData = json_encode(
            array('receipt-data' => $receipt)
        );
        //正式购买地址 沙盒购买地址
        $url_buy     = "https://buy.itunes.apple.com/verifyReceipt";
        $url_sandbox = "https://sandbox.itunes.apple.com/verifyReceipt";
        $url = $sandbox ? $url_sandbox : $url_buy;

        //简单的curl
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        $response = curl_exec($ch);
        $errno    = curl_errno($ch);
        curl_close($ch);
        if ($errno != 0) {
            throw new \LogicException('请求超时，请稍后重试',1033);
        }
        /**
         * $data['status']==0  成功
         * $data['receipt']['in_app'][0]['transaction_id']  苹果订单号
         * $data['receipt']['in_app'][0]['product_id'];  商品价格
         */
        $data = json_decode($response, true);
        if (!is_array($data)) {
            throw new \LogicException('苹果返回数据有误，请稍后重试',1034);
        }
        if (!isset($data['status']) || $data['status'] != 0) {
            throw new \LogicException('购买失败',1035);
        }
        //返回产品的信息
        return $data['receipt'];
    }
}